﻿using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Devonline.Core;
using Microsoft.AspNetCore.Identity;

namespace Devonline.Identity
{
    /// <summary>
    /// 角色, 字符串类型的默认实现
    /// </summary>
    [Table("role"), DisplayName("角色")]
    public class Role : Role<string>
    {
    }

    /// <summary>
    /// 角色, 字符串类型的默认实现
    /// </summary>
    [Table("role"), DisplayName("角色")]
    public class Role<TKey> : IdentityRole<TKey>, IIdentity<TKey> where TKey : IEquatable<TKey>, IConvertible
    {
        public Role()
        {
            Id = KeyGenerator.GetKey<TKey>();
            RowVersion = Id;
        }

        /// <summary>
        /// 数据主键
        /// </summary>
        [Column("id"), DisplayName("编号"), DatabaseGenerated(DatabaseGeneratedOption.None), Key, MaxLength(36), Excel]
        public override TKey Id { get; set; }
        /// <summary>
        /// 名称
        /// </summary>
        [Column("name"), Required, Unique, MaxLength(64), DisplayName("名称")]
        public override string Name { get; set; }
        /// <summary>
        /// 昵称
        /// </summary>
        [Column("alias"), MaxLength(36), DisplayName("昵称")]
        public virtual string Alias { get; set; }
        /// <summary>
        /// 头像
        /// </summary>
        [Column("image"), MaxLength(128), DisplayName("头像")]
        public virtual string Image { get; set; }
        /// <summary>
        /// 身份类型
        /// </summary>
        [Column("type", TypeName = "VARCHAR(16)"), DisplayName("身份类型"), DefaultValue(IdentityType.Internal), Excel]
        public virtual IdentityType Type { get; set; }
        /// <summary>
        /// 行版本号
        /// </summary>
        [Column("row_version"), DisplayName("行版本号"), ConcurrencyCheck]
        public virtual TKey RowVersion { get; set; }
        /// <summary>
        /// 数据状态
        /// </summary>
        [Column("state", TypeName = "VARCHAR(16)"), DisplayName("数据状态"), DefaultValue(DataState.Available), Excel]
        public virtual DataState State { get; set; }
        /// <summary>
        /// 创建时间
        /// </summary>
        [Column("created_on"), DisplayName("创建时间"), Excel]
        public virtual DateTime? CreatedOn { get; set; }
        /// <summary>
        /// 创建人
        /// </summary>
        [Column("created_by"), DisplayName("创建人"), MaxLength(36), Excel]
        public virtual string CreatedBy { get; set; }
        /// <summary>
        /// 更新时间
        /// </summary>
        [Column("updated_on"), DisplayName("更新时间"), Excel]
        public virtual DateTime? UpdatedOn { get; set; }
        /// <summary>
        /// 更新人
        /// </summary>
        [Column("updated_by"), DisplayName("更新人"), MaxLength(36), Excel]
        public virtual string UpdatedBy { get; set; }
        /// <summary>
        /// 备注说明
        /// </summary>
        [Column("description"), DisplayName("备注说明"), MaxLength(256), Excel]
        public virtual string Description { get; set; }
        /// <summary>
        /// Gets or sets the normalized name for this role
        /// </summary>
        [Column("normalized_name"), MaxLength(64), DisplayName("归一角色名")]
        public override string NormalizedName { get; set; }
        /// <summary>
        /// A random value that should change whenever a role is persisted to the store
        /// </summary>
        [Column("concurrency_stamp"), MaxLength(36)]
        public override string ConcurrencyStamp { get; set; }

        /// <summary>
        /// 创建方法
        /// </summary>
        public virtual void Create(string createdBy = null)
        {
            Id ??= KeyGenerator.GetKey<TKey>();
            CreatedOn ??= DateTime.UtcNow;
            CreatedBy ??= createdBy ?? AppSettings.USER_SYSTEM;
        }

        /// <summary>
        /// 更新方法
        /// </summary>
        public virtual void Update(string updatedBy = null)
        {
            RowVersion = KeyGenerator.GetKey<TKey>();
            UpdatedOn ??= DateTime.UtcNow;
            UpdatedBy ??= updatedBy ?? AppSettings.USER_SYSTEM;
        }
    }
}
